<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class Transaction extends Model
{
    protected $table = 'transactions';

    // 不使用自增主键，使用雪花ID
    public $incrementing = false;
    protected $keyType = 'string';

    // 交易类型常量
    const TYPE_INCOME = 'income';    // 入账
    const TYPE_EXPENSE = 'expense';  // 出账

    // 入账子类型常量
    const SUB_TYPE_RECHARGE = 'recharge';           // 充值
    const SUB_TYPE_REFUND_TICKET = 'refund_ticket'; // 退款退票
    const SUB_TYPE_PLATFORM_ADD = 'platform_add';   // 平台加款

    // 出账子类型常量
    const SUB_TYPE_SETTLEMENT = 'settlement';        // 结算
    const SUB_TYPE_BALANCE_REFUND = 'balance_refund'; // 余额退账

    // 交易状态常量
    const STATUS_PENDING = 'pending';       // 待处理
    const STATUS_PROCESSING = 'processing'; // 处理中
    const STATUS_COMPLETED = 'completed';   // 已完成
    const STATUS_FAILED = 'failed';         // 失败
    const STATUS_CANCELLED = 'cancelled';   // 已取消

    protected $fillable = [
        'id',
        'tenant_id',
        'transaction_number',
        'type',
        'sub_type',
        'amount',
        'balance_after',
        'landing_company',  // 修改为外键
        'status',
        'summary',
        'description',
        'metadata',
        'transaction_time',
        'processed_at',
        'created_by',
        'processed_by'
    ];

    protected $casts = [
        'id' => 'string',
        'amount' => 'decimal:2',
        'balance_after' => 'decimal:2',
        'metadata' => 'array',
        'transaction_time' => 'datetime',
        'processed_at' => 'datetime',
        'created_at' => 'datetime',
        'updated_at' => 'datetime',
    ];

    protected $appends = [
        'type_display',
        'sub_type_display', 
        'status_display',
        'transaction_id'
    ];

    /**
     * 生成雪花ID
     */
    public static function generateSnowflakeId(): string
    {
        // 时间戳（毫秒）
        $timestamp = (int)(microtime(true) * 1000);
        
        // 机器ID（这里使用简单的随机数，生产环境应该使用配置的机器ID）
        $machineId = mt_rand(0, 1023); // 10位
        
        // 序列号（这里使用简单的随机数，生产环境应该使用递增序列）
        $sequence = mt_rand(0, 4095); // 12位
        
        // 组装雪花ID: 时间戳(42位) + 机器ID(10位) + 序列号(12位)
        $snowflakeId = ($timestamp << 22) | ($machineId << 12) | $sequence;
        
        return (string)$snowflakeId;
    }

    /**
     * 生成交易单号
     */
    public static function generateTransactionNumber(): string
    {
        // 使用微秒时间戳确保唯一性
        $timestamp = str_replace('.', '', microtime(true) * 10000);
        return 'TXN' . substr($timestamp, -12) . mt_rand(10, 99);
    }

    /**
     * 创建时自动生成雪花ID和交易单号
     */
    protected static function boot()
    {
        parent::boot();
        
        static::creating(function ($model) {
            if (empty($model->id)) {
                $model->id = static::generateSnowflakeId();
            }
            if (empty($model->transaction_number)) {
                $model->transaction_number = static::generateTransactionNumber();
            }
            if (empty($model->transaction_time)) {
                $model->transaction_time = now();
            }
        });
    }

    /**
     * 获取类型显示文本
     */
    public function getTypeDisplayAttribute(): string
    {
        $typeMap = [
            self::TYPE_INCOME => '入账',
            self::TYPE_EXPENSE => '出账'
        ];

        return $typeMap[$this->type] ?? '未知类型';
    }

    /**
     * 获取子类型显示文本
     */
    public function getSubTypeDisplayAttribute(): string
    {
        $subTypeMap = [
            // 入账子类型
            self::SUB_TYPE_RECHARGE => '充值',
            self::SUB_TYPE_REFUND_TICKET => '退款退票',
            self::SUB_TYPE_PLATFORM_ADD => '平台加款',
            // 出账子类型
            self::SUB_TYPE_SETTLEMENT => '结算',
            self::SUB_TYPE_BALANCE_REFUND => '余额退账'
        ];

        return $subTypeMap[$this->sub_type] ?? '未知子类型';
    }

    /**
     * 获取状态显示文本
     */
    public function getStatusDisplayAttribute(): string
    {
        $statusMap = [
            self::STATUS_PENDING => '待处理',
            self::STATUS_PROCESSING => '处理中',
            self::STATUS_COMPLETED => '已完成',
            self::STATUS_FAILED => '失败',
            self::STATUS_CANCELLED => '已取消'
        ];

        return $statusMap[$this->status] ?? '未知状态';
    }

    /**
     * 获取交易ID（显示用）
     */
    public function getTransactionIdAttribute(): string
    {
        return 'TXN' . substr($this->id, -8);
    }

    public function getIdAttribute($value): string
    {
        return (string) $value;
    }

    /**
     * 关联租户
     */
    public function tenant(): BelongsTo
    {
        return $this->belongsTo(Tenant::class);
    }

    /**
     * 关联落地公司
     */
    public function landingCompany(): BelongsTo
    {
        return $this->belongsTo(LandingCompany::class);
    }

    /**
     * 租户作用域
     */
    public function scopeTenant($query, $tenantId)
    {
        return $query->where('tenant_id', $tenantId);
    }

    /**
     * 类型作用域
     */
    public function scopeType($query, $type)
    {
        return $query->where('type', $type);
    }

    /**
     * 子类型作用域
     */
    public function scopeSubType($query, $subType)
    {
        return $query->where('sub_type', $subType);
    }

    /**
     * 状态作用域
     */
    public function scopeStatus($query, $status)
    {
        return $query->where('status', $status);
    }

    /**
     * 按账单ID搜索
     */
    public function scopeSearchTransactionId($query, $transactionId)
    {
        return $query->where('transaction_number', 'like', "%{$transactionId}%")
                    ->orWhere('id', 'like', "%{$transactionId}%");
    }

    /**
     * 按交易时间范围筛选
     */
    public function scopeTransactionTimeRange($query, $startDate, $endDate)
    {
        return $query->whereBetween('transaction_time', [$startDate, $endDate]);
    }

    /**
     * 获取入账子类型选项
     */
    public static function getIncomeSubTypes(): array
    {
        return [
            self::SUB_TYPE_RECHARGE => '充值',
            self::SUB_TYPE_REFUND_TICKET => '退款退票',
            self::SUB_TYPE_PLATFORM_ADD => '平台加款'
        ];
    }

    /**
     * 获取出账子类型选项
     */
    public static function getExpenseSubTypes(): array
    {
        return [
            self::SUB_TYPE_SETTLEMENT => '结算',
            self::SUB_TYPE_BALANCE_REFUND => '余额退账'
        ];
    }

    /**
     * 获取所有状态选项
     */
    public static function getStatusOptions(): array
    {
        return [
            self::STATUS_PENDING => '待处理',
            self::STATUS_PROCESSING => '处理中',
            self::STATUS_COMPLETED => '已完成',
            self::STATUS_FAILED => '失败',
            self::STATUS_CANCELLED => '已取消'
        ];
    }
}
